對於我們的專案我們需要再完成API開發後需要練習寫一些自動化測試, 所以針對這個部分做了一點小小的研究。
測試是什麼?
測試的定義
測試是一系列的活動,簡單來說就是確認在預期的條件和環境下, 程式碼跑出來的結果是否符和我們的預期。
一個好的測試我認為應該具備:
隔離:確保測試的獨立性,避免外部因素干擾。
簡單來說就是, 先確認測試的目標, 那你就實際去跑那個目標其他部分用模擬的, 這樣做有什麼好處呢? 我認為是不會受到一些外部因素的干擾你要測試的部分, 比如:
你今天要測試A功能, 但你實際跑了A和B, 那這樣如果出了錯誤, 那到底是A的問題還是B的問題?就是觀察的對象不那麼的聚焦。
速度:
測試應該快速執行。因為在實際開發中,我們希望能夠頻繁地執行測試,以確認每一次的更改都不會引入新的錯誤。但如果測試太慢,慢到你不如實際去用postman打(我沒實際看過慢可以多慢所以只是舉個例子)。
可重複性:
不同的人,在不同的時間,不同的環境下執行測試,都應該得到相同的結果。
可維護性:
隨著軟體的演進,測試也需要更新。一個好的測試應該易於維護,以適應新的需求或變更。
明確性:
當測試失敗時,應該能夠快速地識別是哪部分程式碼或功能出了問題。
完整性:
雖然我們不能窮盡所有的測試情境,但應該儘量涵蓋所有可能的核心功能和邊界情況。
基本步驟
這裡我想說用一個簡單的例子說明,什麼樣算一個簡單的測試:
以下是一些基本架構
比如這裡測試的目標是Calculator裡面的add() method
清理(Tear Down):如果需要,清除任何你在測試中創建的資源。
這樣讓每一次測試都盡量互相獨立不干擾
public function testAdd() {
$calculator = new Calculator(); // 設定
$result = $calculator->add(2, 3); // 執行
$this->assertEquals(5, $result); // 驗證
// 清理(在這個情況下不需要)
}
設定的部分就是如何去call你想測試的function
執行的部分就是實際去call function
驗證的部分就是將你call function的回傳值和預期的值同時書入$this->assertEquals()去做比較,所以這裡如果你輸入5然後他返回的計算結果也是5的話,就是正確。
如何執行
基本指令
創建
安裝套件
composer require --dev phpunit/phpunit
新增feature test
php artisan make:test NameOfYourTest
新增unit test
php artisan make:test NameOfYourUnitTest --unit
執行
所以有的單元測試。
./vendor/bin/phpunit TestCase
or
也可以用laravel開
php artisan test tests/Unit/PokemonStoreTest.php
所有的功能測試
./vendor/bin/phpunit --testsuite Feature
單一測試執行(透過filter指令可以讓你執行你想要的function, 不會一次執行(還在寫測試的階段會用到)
./vendor/bin/phpunit --filter indexTest
什麼樣的程式碼需要寫測試
我對於什麼樣的程式碼要寫測試, 一直困擾我許久, 我覺得這是有點需要經驗, 就我目前所問到的主要有幾個判斷依據:
一. 這段程式碼的的重要程度
二.這段程式碼和其他程式碼的耦合程度
三.是否為laravel 內建的一些方法, 如果是基本上我認為不太需要個別的去寫單元測試,
比方說laravel的驗證規則:
return [
'name' => 'required|string|max:255',
'race_id' => 'required|integer|exists:races,id',
'ability_id' => 'required|integer|exists:abilities,id',
'nature_id' => 'required|integer|exists:natures,id',
'level' => 'required|integer|max:100'
'skills' => 'required|array|min:1|max:4'
];
這裡假如要寫的話, 可能我要測試沒有輸入name的時候, name輸入值為int的時候, name輸入超過255的時候…..。
我請教幾個前輩, 給我的建議事項這種laravel內建的一些驗證規則, 只要你有引用到, 應該不容易出錯誤, 而我自己認為我可能寫一個測試, 確認我有引用到這個驗證規則就好了。
四.是否為自己寫的功能或驗證邏輯
我認為自己寫的可能就不像laravel的這樣做過各種測試, 所以可以自己寫來做驗證。
但以上我認為都是依據當時情況:
比如今天你的案子很趕,那當然沒有時間寫,如果是有一點點時間,那就是挑重要的或是耦合性較高的寫,總之我認為就是要根據情況做取捨。
後續還會分享一些寫測試要注意的事情以及,我是如何寫測試以及我遇到什麼問題。